// 封装接口请求工具类
import 'package:dio/dio.dart';
// import 'package:flutter/material.dart';
import 'package:shenling_logistics/utils/eventBus.dart';
import 'package:shenling_logistics/utils/token.dart';

class HttpService {
  // 创建dio实例
  final Dio _dio = Dio();

  // 2.构造函数中创建基地址配置
  HttpService() {
    _dio.options.baseUrl = 'https://slwl-api.itheima.net';
    // 配置连接超时时间
    _dio.options.connectTimeout = Duration(seconds: 20);
    // 配置响应超时时间
    _dio.options.receiveTimeout = Duration(seconds: 20);
    // 配置请求头
    _dio.options.headers = {'Content-Type': 'application/json'};
    // 添加请求和响应拦截器
    _addInterceptors();
  }

  // 3.添加拦截器
  _addInterceptors() {
    // 添加请求拦截器
    _dio.interceptors.add(
      InterceptorsWrapper(
        onRequest: (RequestOptions options, RequestInterceptorHandler handler) {
          // 请求拦截器，添加公共请求参数，token
          // 获取从本地获取token,如果没有，返回空字符串
          final token = TokenManager().getToken() ?? '';
          if (token.isNotEmpty) {
            // 如果token不为空，则添加token到请求头中
            options.headers['Authorization'] = token;
          }
          return handler.next(options);
        },
        onResponse: (Response response, ResponseInterceptorHandler handler) {
          // 响应拦截器，统一处理成功响应

          return handler.next(response);
        },
        onError: (DioException error, ErrorInterceptorHandler handler) {
          // 响应拦截器，统一处理错误响应
          return handler.next(error);
        },
      ),
    );
  }

  // 4.定义get请求方法
  Future<dynamic> get(String url, {Map<String, dynamic>? params}) async {
    try {
      final res = await _dio.get(url, queryParameters: params);
      // 调用统一处理成功响应
      return _handleSuccess(res);
    } catch (e) {
      // 调用统一处理错误响应
      return _handleError(e);
    }
  }

  // 5.定义post请求方法
  Future<dynamic> post(String url, Map<String, dynamic> data) async {
    try {
      final res = await _dio.post(url, data: data);
      return _handleSuccess(res);
    } catch (e) {
      return _handleError(e);
    }
  }

  // 6.定义put请求方法
  Future<dynamic> put(String url, Map<String, dynamic> data) async {
    try {
      final res = await _dio.put(url, data: data);
      return _handleSuccess(res);
    } catch (e) {
      return _handleError(e);
    }
  }

  // 统一处理成功响应
  _handleSuccess(Response response) {
    // 处理成功响应
    if (response.statusCode! >= 200 && response.statusCode! < 300) {
      return response.data;
    } else {
      // 抛出请求失败状态码
      throw Exception('请求失败，状态码: ${response.statusCode}');
    }
  }

  // 统一处理错误响应
  _handleError(error) async {
    if (error is DioException) {
      if (error.type == DioExceptionType.connectionTimeout ||
          error.type == DioExceptionType.receiveTimeout) {
        throw Exception('网络连接超时');
      } else if (error.type == DioExceptionType.badResponse) {
        if (error.response?.statusCode == 401) {
          // 登录失效 或  token过期
          // 1.删除本地存储的token
          await TokenManager().removeToken();
          // 2.非widget页面，发布事件，通知跳转到登录页
          eventBus.fire(LogoutEvent());
        } else {
          // 抛出请求失败状态码
          throw Exception('请求失败，状态码: ${error.response?.statusCode}');
        }
      } else {
        throw Exception('网络请求错误:$error');
      }
    } else {
      throw Exception('未知错误:$error');
    }
  }
}

// 导出  HttpService单例
final http = HttpService();
